
/*
This file is part of MJIN2.

Copyright (C) 2012-2013 Opensource Game Studio

This software is provided 'as-is', without any express or implied
warranty.  In no event will the authors be held liable for any damages
arising from the use of this software.

Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:

1. The origin of this software must not be misrepresented; you must not
   claim that you wrote the original software. If you use this software
   in a product, an acknowledgment in the product documentation would be
   appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
   misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/

#ifndef MJIN2_COMMON_H
#define MJIN2_COMMON_H

#include <mjin2/Exception.h>
#include <mjin2/TypeDefs.h>
#include <mjin2/Vec3.h>
#include <mjin2/Vec4.h>
#include <mjin2/VideoInfo.h>

namespace mjin2
{

//! Platform dependent implementation.
//! \return MJIN2 version, build date, GCC version, MJIN2 compile options.
String buildInfo() throw ();
//! Run command until its completion to get output.

//! \return True if command succeeded, false otherwise.
bool cmd(const String &command, StringList &output) throw ();
//! Convert degree rotation to quaternion. Useful for user input.
Vec4 degreeToQuaternion(const Vec3 &degree) throw ();
//! Try to find out what distribution MJIN2 runs on at the moment.

/*! Platform dependent implementation.
 *
 * Linux:
 * - try /etc/os-release
 * - if previous failed, try /etc/.*release and /etc/.*version
 * - if previous failed, return "Linux Unknown"
 *
 * Windows:
 * - run ver.exe
 * - if previous failed, return "Windows Unknown"
 */
String distribution() throw (Exception);
//! Run command with xdg-open on Linux, or by shell on Windows. Open web pages with it.

//! Platform dependent implementation.
void execute(const String &command) throw ();
//! Filter list according to the pattern.
StringList filterList(const StringList &list,
                      const String     &pattern,
                      bool             caseSensitive = true) throw (Exception);
//! \param language If provided, save the value of locale language into there.
//! \param country  If provided, save the value of locale country  into there.
//! \param modifier If provided, save the value of locale modifier into there.
//! Platform dependent implementation.
//! \return LC_MESSAGES value for Linux, language_COUNTRY for Windows.
/*
String locale(String *language = 0,
              String *country  = 0,
              String *modifier = 0);
              */
//! List files or directories.
StringList listFiles(const String &dir) throw (Exception);
//! Make directory and possibly all intermediate ones too.
void mkdir(const String &dir) throw (Exception);
//! Find out if directory or file exists.
bool pathExists(const String &path) throw (Exception);
//! rand() that works correctly across platforms.
//! \param randomize Multiply by current time.
u32 rand(bool randomize = false) throw ();
//! Remove directory or file.

//! If you try to remove path that does not exist, it will raise exception.
void removePath(const String &path) throw (Exception);
//! Sum two quaternion rotations (performs quaternion multiplication).
Vec4 rotationSum(const Vec4 &r1, const Vec4 &r2) throw ();
//! Platform dependent implementation.
//void setDefaultLocale();
//! srand() that works correctly across platforms.
void srand(u32 seed) throw ();
//! Join several strings into one delimited by the separator.
String strJoin(const String &separator, const StringList &list) throw ();
//! Find out if string matches the pattern.

//! If you need to perform match in a loop, use RegExp::match() instead,
//! because strMatch creates/deletes RegExp instance when it's called.
bool strMatch(const String &string,
              const String &pattern,
              bool         caseSensitive = true) throw (Exception);
//! Replace pattern in the string with the replacement.
String strReplace(const String &string,
                  const String &pattern,
                  const String &replacement,
                  bool         all           = true,
                  bool         caseSensitive = true) throw (Exception);
//! Split string into the list of strings.
StringList strSplit(const String &string,
                    const String &pattern,
                    bool         caseSensitive = true) throw (Exception);
//! Variable argument list to string.

//! Do not use this function directly. Use MJIN2_STR / MJIN2_CSTR macros instead.
String vaToStr(const char *fmt, ...) throw ();
//! MJIN2 version.
String version();

} // namespace mjin2

//! Macro to disable copy constructor and operator= functions. Private use only.
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
    TypeName(const TypeName&);             \
    void operator=(const TypeName&)

//! Convenient macro for creating String with printf-like format.
/*! Example:
 * \code
 * u32 i = 10;
 * String a = "Something";
 * String s = MJIN2_STR("ID: %u Value: %s", i, a.c_str());
 * std::cout << s << std::endl;
 * \endcode
 * The above example will print "ID: 10 Value: Something".
 */
#define MJIN2_STR(...)  mjin2::vaToStr(__VA_ARGS__)
//! Convenient macro for creating C string with printf-like format.

//! \see MJIN2_STR()
#define MJIN2_CSTR(...) mjin2::vaToStr(__VA_ARGS__).c_str()

#endif // MJIN2_COMMON_H

